using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Text;

namespace Galaktika.BI.Silverlight.ClientApp.Web.Runtime.DataAccess
{
    using Galaktika.BI.Extensibility.Dom;
    using Galaktika.BI.Extensibility.Dom.Dac;
    using Galaktika.BI.Silverlight.ClientApp.Web.Runtime.Services;

    public class OleDbDataManager : IDataManager
    {
        private string m_ConnStr;
        private string m_Query;
        public OleDbDataManager(string connStr, string query)
        {
            m_ConnStr = connStr;
            m_Query = query;
        }

        #region IDataManager Members

        public string Name
        {
            get
            {
                return m_Query.GetHashCode().ToString();
            }
        }

        public object this[IBindingContext context]
        {
            get 
            {
                return this.CreateBindObject(context);
            }
        }

        public object this[string name]
        {
            get
            {
                switch (name)
                {
                    case "CONNECTION_STRING":
                        return m_ConnStr;
                    case "QUERY":
                        return m_Query;
                    default:
                        return string.Empty;
                }
            }
            set
            {
                switch (name)
                {
                    case "CONNECTION_STRING":
                        m_ConnStr = (string)value;
                        break;
                    case "QUERY":
                        m_Query = (string)value;
                        break;
                }
            }
        }

        #endregion

        public bool Cancel()
        {
            // TODO: Lock
            if (m_CurrentCmd != null)
            {
                m_CurrentCmd.Cancel();
            }

            return true;
        }

        private OleDbCommand m_CurrentCmd;
        private object CreateBindObject(IBindingContext context)
        {
            DataTable obj = null;

            IExecutionContext exe = (IExecutionContext)context.Services.GetService(typeof(IExecutionContext));
            using (OleDbConnection conn = new OleDbConnection(exe.Parse(context, m_ConnStr)))
            {
                conn.Open();
                using (OleDbCommand cmd = new OleDbCommand(exe.Parse(context, m_Query), conn))
                {
                    m_CurrentCmd = cmd;
                    using (OleDbDataAdapter adapter = new OleDbDataAdapter(cmd))
                    {
                        DataTable table = new DataTable();
                        adapter.FillSchema(table, SchemaType.Source);
                        adapter.Fill(table);

                        obj = table;
                    }
                    m_CurrentCmd = null;
                }
                conn.Close();
            }

            if (obj != null)
            {
                return DataTableHelper.Create(obj);
            }

            return obj;
        }
    }
}
